package com.circle.model.module;

import com.circle.model.util.DbUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DbDao {
    private Connection conn;
    private PreparedStatement pstmt;
    private ResultSet rs;

    /**
     * 执行查询操作
     * @param sql SQL语句
     * @param params 查询参数
     * @return 查询结果列表
     */
    public List<Map<String, Object>> executeQuery(String sql, Object... params) throws SQLException {
        List<Map<String, Object>> resultList = new ArrayList<>();
        try {
            conn = DbUtil.getConnection();
            pstmt = conn.prepareStatement(sql);
            // 设置参数
            for (int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]);
            }
            rs = pstmt.executeQuery();
            
            // 获取结果集元数据
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            
            // 遍历结果集
            while (rs.next()) {
                Map<String, Object> row = new HashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnName(i);
                    Object value = rs.getObject(i);
                    row.put(columnName, value);
                }
                resultList.add(row);
            }
        } finally {
            closeResources();
        }
        return resultList;
    }

    /**
     * 执行更新操作（增、删、改）
     * @param sql SQL语句
     * @param params 参数
     * @return 影响的行数
     */
    public int executeUpdate(String sql, Object... params) throws SQLException {
        try {
            conn = DbUtil.getConnection();
            pstmt = conn.prepareStatement(sql);
            // 设置参数
            for (int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]);
            }
            return pstmt.executeUpdate();
        } finally {
            closeResources();
        }
    }

    /**
     * 批量执行更新操作
     * @param sql SQL语句
     * @param paramsList 参数列表
     * @return 每个操作影响的行数数组
     */
    public int[] executeBatch(String sql, List<Object[]> paramsList) throws SQLException {
        try {
            conn = DbUtil.getConnection();
            conn.setAutoCommit(false);
            pstmt = conn.prepareStatement(sql);
            
            // 添加批处理
            for (Object[] params : paramsList) {
                for (int i = 0; i < params.length; i++) {
                    pstmt.setObject(i + 1, params[i]);
                }
                pstmt.addBatch();
            }
            
            // 执行批处理
            int[] results = pstmt.executeBatch();
            conn.commit();
            return results;
        } catch (SQLException e) {
            if (conn != null) {
                conn.rollback();
            }
            throw e;
        } finally {
            if (conn != null) {
                conn.setAutoCommit(true);
            }
            closeResources();
        }
    }

    /**
     * 执行插入操作并返回生成的主键
     * @param sql SQL语句
     * @param params 参数
     * @return 生成的主键
     */
    public long executeInsertWithGeneratedKey(String sql, Object... params) throws SQLException {
        try {
            conn = DbUtil.getConnection();
            pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            // 设置参数
            for (int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]);
            }
            pstmt.executeUpdate();
            
            // 获取生成的主键
            rs = pstmt.getGeneratedKeys();
            if (rs.next()) {
                return rs.getLong(1);
            }
            return -1;
        } finally {
            closeResources();
        }
    }

    /**
     * 关闭资源
     */
    private void closeResources() {
        try {
            if (rs != null) {
                rs.close();
            }
            if (pstmt != null) {
                pstmt.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
